package com.deluxelx.soul.inn.service.chat.impl;

import cn.hutool.core.util.StrUtil;
import com.deluxelx.soul.inn.bean.chat.*;
import com.deluxelx.soul.inn.bean.counselor.Counselor;
import com.deluxelx.soul.inn.bean.user.User;
import com.deluxelx.soul.inn.common.enums.ChatTypeEnum;
import com.deluxelx.soul.inn.common.util.DateTimeUtil;
import com.deluxelx.soul.inn.common.util.EncryptionUtil;
import com.deluxelx.soul.inn.common.util.RedisUtil;
import com.deluxelx.soul.inn.mapper.counselor.CounselorMapper;
import com.deluxelx.soul.inn.mapper.user.UserMapper;
import com.deluxelx.soul.inn.service.chat.ChatRecordsService;
import com.deluxelx.soul.inn.service.chat.ChatRoomService;
import com.deluxelx.soul.inn.service.chat.ChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.deluxelx.soul.inn.common.constant.ChatConstant.*;
import static com.deluxelx.soul.inn.common.constant.CounselorConstant.COUNSELOR_CACHE_KEY;
import static com.deluxelx.soul.inn.common.constant.UserRole.*;

/**
 * 聊天功能服务实现类
 *
 * @author liaozihao
 * @date 2024-04-26 11:49
 */
@Service
@Slf4j
public class ChatServiceImpl implements ChatService {

    @Resource
    private ChatRoomService chatRoomService;

    @Resource
    private ChatRecordsService chatRecordsService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private CounselorMapper counselorMapper;

    @Resource
    private RedisUtil redisUtil;

    public static final Map<String, ChatterVO> CHATTER_MAP = new HashMap<>();

    @Override
    public List<ChatRoomVO> fetchChatRoomList(String userId) {
        if (StrUtil.isBlank(userId)) {
            log.error("method-[fetchChatRoomList]：userId is null");
            return Collections.emptyList();
        }
        List<ChatRoom> chatRoomList = chatRoomService.lambdaQuery()
                .eq(ChatRoom::getDeleteFlag, 0)
                .and(i -> i.eq(ChatRoom::getStartChatterId, userId).or().eq(ChatRoom::getReceiveChatterId, userId))
                .orderByDesc(ChatRoom::getLastChatTime)
                .list();
        List<ChatRoomVO> result = new ArrayList<>();
        for (ChatRoom chatRoom : chatRoomList) {
            ChatRoomVO chatRoomVO = new ChatRoomVO();
            chatRoomVO.setId(chatRoom.getId());
            chatRoomVO.setLastChatTimeStr(DateTimeUtil.getChatTimeStr(chatRoom.getLastChatTime()));
            chatRoomVO.setLastChatMsg(chatRoom.getLastChatMsg());
            ChatterVO chatterVO = new ChatterVO();
            String chatterId = userId.equals(chatRoom.getStartChatterId())
                    ? chatRoom.getReceiveChatterId() : chatRoom.getStartChatterId();
            chatterVO.setChatterId(chatterId);
            if (redisUtil.sHasKey(COUNSELOR_CACHE_KEY, chatterId)) {
                Counselor counselor = counselorMapper.selectById(chatterId);
                chatterVO.setChatterName(counselor.getName());
                chatterVO.setChatterAvatar(counselor.getAvatar());
                chatterVO.setRole(COUNSELOR_ROLE);
            } else {
                User user = userMapper.selectById(chatterId);
                chatterVO.setChatterName(user.getNickName());
                chatterVO.setChatterAvatar(user.getAvatar());
                chatterVO.setRole(NORMAL_ROLE);
            }
            if (!CHATTER_MAP.containsKey(chatterId)) {
                CHATTER_MAP.put(chatterId, chatterVO);
            }
            chatRoomVO.setChatterVO(chatterVO);
            result.add(chatRoomVO);
        }
        return result;
    }

    @Override
    public ChatRecordsVO fetchChatRecords(ChatRecordsParam param) {
        if (param == null) {
            return null;
        }
        ChatRecordsVO chatRecordsVO = new ChatRecordsVO();
        String chatRoomId = param.getChatRoomId();
        if (StrUtil.isNotEmpty(chatRoomId)) {
            List<ChatRecords> chatRecords = chatRecordsService.lambdaQuery()
                    .eq(ChatRecords::getChatRoomId, chatRoomId)
                    .orderByDesc(ChatRecords::getSendTime)
                    .list();
            List<ChatRecordsItem> result = new ArrayList<>();
            for (ChatRecords records : chatRecords) {
                ChatRecordsItem chatRecordsItem = new ChatRecordsItem();
                chatRecordsItem.setId(records.getId());
                chatRecordsItem.setChatRoomId(chatRoomId);
                chatRecordsItem.setSendTimeStr(DateTimeUtil.getChatTimeStr(records.getSendTime()));
                chatRecordsItem.setFromChatter(CHATTER_MAP.get(records.getFromChatterId()));
                chatRecordsItem.setToChatter(CHATTER_MAP.get(records.getToChatterId()));
                chatRecordsItem.setMsg(records.getMsg());
                result.add(chatRecordsItem);
            }

            chatRecordsVO.setType(EXIST_CHATROOM);
            chatRecordsVO.setChatRoomId(chatRoomId);
            chatRecordsVO.setRecords(result);
        } else {
            String userId = param.getUserId();
            String counselorId = param.getCounselorId();
            ChatRoom chatRoom = new ChatRoom();
            chatRoomId = EncryptionUtil.chatRoomEncrypt(userId, counselorId);
            chatRoom.setId(chatRoomId);
            chatRoom.setStartChatterId(userId);
            chatRoom.setReceiveChatterId(counselorId);
            chatRoom.setStartChatTime(LocalDateTime.now());
            chatRoom.setTypeCode(COUNSELOR_CHAT);
            chatRoom.setCounselorIdentity(ChatTypeEnum.RECEIVE_IS_COUNSELOR.getName());
            chatRoomService.save(chatRoom);

            chatRecordsVO.setType(NEW_CHATROOM);
            chatRecordsVO.setChatRoomId(chatRoomId);
            chatRecordsVO.setRecords(Collections.emptyList());
        }
        return chatRecordsVO;
    }
}
